package com.ruoyi.business.jisuController;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.DO.RetrievalSearchResult;
import com.ruoyi.system.domain.vo.R;
import com.ruoyi.system.protocol.IDynamicDataService;
import com.ruoyi.system.protocol.IDynamicSearchService;
import org.apache.commons.math3.analysis.function.Constant;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

@RestController
@RequestMapping("ownJSApi/statistics")
public class JiShuStatisticsController {

    @Autowired
    private IDynamicSearchService dynamicSearchService;
    @Autowired
    private IDynamicDataService dynamicDataService;
    @Autowired
    private RedisCache redisCache;

    private final static String INDEX = "jisu_log";

    private final static String CLASSESEN = "jisukeji";


    @RequestMapping("/list")
    public R list() {
        String businessTypeStr = ServletUtils.getParameter("businessTypeStr");
        int pageNum = ServletUtils.getParameterToInt("pageNum");
        int pageSize = ServletUtils.getParameterToInt("pageSize");
        String channelId = ServletUtils.getParameter("channelId");
        String mki = ServletUtils.getParameter("mki");
        String beginTime = ServletUtils.getParameter("beginTime");
        String endTime = ServletUtils.getParameter("endTime");

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if(StringUtils.isNotEmpty(businessTypeStr)){
            boolQueryBuilder.must(QueryBuilders.termQuery("businessTypeStr.keyword", businessTypeStr));
        }
        if(StringUtils.isNotEmpty(mki)){
            boolQueryBuilder.must(QueryBuilders.termQuery("dmpid.keyword", mki));
        }
        if(StringUtils.isNotEmpty(channelId)){
            boolQueryBuilder.must(QueryBuilders.termQuery("params.channelId.keyword", channelId));
        }
        if(StringUtils.isNotEmpty(beginTime) && StringUtils.isNotEmpty(endTime)){
            boolQueryBuilder.must(new RangeQueryBuilder("createTimeStr.keyword").gte(beginTime).lte(endTime).format("yyyy-MM-dd HH:mm:ss"));
        }
        Map<String, String> sortField = new HashMap<>();
        sortField.put("createTimeStr.keyword", "desc");
        HashMap<String, Object> search = dynamicSearchService.search(INDEX, boolQueryBuilder, null, null, sortField, null, pageNum, pageSize);
        return R.success().dataAll(search);
    }

    @RequestMapping("/channelList")
    public R channelList() {
        Long dynamicDataCount = dynamicDataService.getDynamicDataCount(CLASSESEN, null);
        List<Map<String, Object>> dynamicData = dynamicDataService.getDynamicData(CLASSESEN, null, null, null, 1, dynamicDataCount.intValue());
        return R.success().data("list", dynamicData);
    }


    @RequestMapping("/statisticsTime")
    public R statisticsTime() {
        String channelId = ServletUtils.getParameter("channelId");
        String beginTime = ServletUtils.getParameter("beginTime");
        String endTime = ServletUtils.getParameter("endTime");
        String dimension = ServletUtils.getParameter("dimension");

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if(StringUtils.isNotEmpty(channelId)){
            boolQueryBuilder.must(QueryBuilders.termQuery("params.channelId.keyword", channelId));
        }
        if(StringUtils.isNotEmpty(beginTime) && StringUtils.isNotEmpty(endTime)){
            boolQueryBuilder.must(new RangeQueryBuilder("createTimeStr.keyword").gte(beginTime).lte(endTime).format("yyyy-MM-dd HH:mm:ss"));
        }

        TermsAggregationBuilder dimensionAgg = AggregationBuilders.terms(dimension).field(dimension+".keyword").size(100);
        Map<String, Object> map = dynamicSearchService.analysisQuery(INDEX, boolQueryBuilder, dimensionAgg);

        return R.success().data("facet", map);
    }

    @RequestMapping("/statisticsChannel")
    public R statisticsChannel() {
        String businessTypeStr = ServletUtils.getParameter("businessTypeStr");
        String channelId = ServletUtils.getParameter("channelId");
        String beginTime = ServletUtils.getParameter("beginTime");
        String endTime = ServletUtils.getParameter("endTime");

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if(StringUtils.isNotEmpty(businessTypeStr)){
            boolQueryBuilder.must(QueryBuilders.termQuery("businessTypeStr.keyword", businessTypeStr));
        }
        if(StringUtils.isNotEmpty(channelId)){
            boolQueryBuilder.must(QueryBuilders.termQuery("params.channelId.keyword", channelId));
        }
        if(StringUtils.isNotEmpty(beginTime) && StringUtils.isNotEmpty(endTime)){
            boolQueryBuilder.must(new RangeQueryBuilder("createTimeStr.keyword").gte(beginTime).lte(endTime).format("yyyy-MM-dd HH:mm:ss"));
        }
        LinkedHashMap<String, LinkedHashMap<String, Object>> facet = dynamicSearchService.facet(INDEX, null, boolQueryBuilder, new String[]{"params.channelId"}, 100);
        if(facet != null && facet.containsKey("params.channelId")){
            LinkedHashMap<String, Object> channelFacetNew = new LinkedHashMap<>();
            LinkedHashMap<String, Object> channelFacet = facet.get("params.channelId");

            Map<String, Object> channelCacheMap = redisCache.getCacheMap(CLASSESEN + "Cache");
            Map<String, Object> channelDetail = null;
            for(String key: channelFacet.keySet()){
                channelDetail = (Map<String, Object>)channelCacheMap.get(key);
                if(channelDetail != null){
                    channelFacetNew.put(channelDetail.get("title")+"", channelFacet.get(key));
                }else{
                    //没有查询到对应的渠道就不显示了
//                    channelFacetNew.put(key, channelFacet.get(key));
                }
            }
            facet.put("params.channelId", channelFacetNew);
        }
        return R.success().data("facet", facet);
    }

    @RequestMapping("/statisticsBusinessType")
    public R statisticsBusinessType() {
        String businessTypeStr = ServletUtils.getParameter("businessTypeStr");
        String channelId = ServletUtils.getParameter("channelId");
        String beginTime = ServletUtils.getParameter("beginTime");
        String endTime = ServletUtils.getParameter("endTime");

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if(StringUtils.isNotEmpty(businessTypeStr)){
            boolQueryBuilder.must(QueryBuilders.termQuery("businessTypeStr.keyword", businessTypeStr));
        }
        if(StringUtils.isNotEmpty(channelId)){
            boolQueryBuilder.must(QueryBuilders.termQuery("params.channelId.keyword", channelId));
        }
        if(StringUtils.isNotEmpty(beginTime) && StringUtils.isNotEmpty(endTime)){
            boolQueryBuilder.must(new RangeQueryBuilder("createTimeStr.keyword").gte(beginTime).lte(endTime).format("yyyy-MM-dd HH:mm:ss"));
        }

        TermsAggregationBuilder channelIdAgg = AggregationBuilders.terms("channelId").field("params.channelId.keyword");
        TermsAggregationBuilder businessTypeStrAgg = AggregationBuilders.terms("businessTypeStr").field("businessTypeStr.keyword");
        channelIdAgg.subAggregation(businessTypeStrAgg);
        Map<String, Object> map = dynamicSearchService.analysisQuery(INDEX, boolQueryBuilder, channelIdAgg);

        Map<String, Object> mapNew = new HashMap<>();
        if(map != null){
            Map<String, Object> channelCacheMap = redisCache.getCacheMap(CLASSESEN + "Cache");
            for(String pkey: map.keySet()){
                mapNew = new HashMap<>();
                Map<String, Object> channelAggMap = (Map<String, Object>)map.get(pkey);
                Map<String, Object> channelDetail = null;
                for(String key: channelAggMap.keySet()){
                    channelDetail = (Map<String, Object>)channelCacheMap.get(key);
                    if(channelDetail != null){
                        mapNew.put(channelDetail.get("title")+"", channelAggMap.get(key));
                    }else{
                        //没有查询到对应的渠道就不显示了
//                        mapNew.put(key, channelAggMap.get(key));
                    }
                }
                map.put(pkey, mapNew);
            }

        }
        return R.success().data("agg", map);
    }


    @RequestMapping("/exportCsv")
    public void exportCsv(HttpServletResponse response) throws UnsupportedEncodingException {
        String businessTypeStr = ServletUtils.getParameter("businessTypeStr");
        int pageNum = ServletUtils.getParameterToInt("pageNum");
        int pageSize = ServletUtils.getParameterToInt("pageSize");
        String channelId = ServletUtils.getParameter("channelId");
        String mki = ServletUtils.getParameter("mki");
        String beginTime = ServletUtils.getParameter("beginTime");
        String endTime = ServletUtils.getParameter("endTime");

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if(StringUtils.isNotEmpty(businessTypeStr)){
            boolQueryBuilder.must(QueryBuilders.termQuery("businessTypeStr.keyword", businessTypeStr));
        }
        if(StringUtils.isNotEmpty(mki)){
            boolQueryBuilder.must(QueryBuilders.termQuery("dmpid.keyword", mki));
        }
        if(StringUtils.isNotEmpty(channelId)){
            boolQueryBuilder.must(QueryBuilders.termQuery("params.channelId.keyword", channelId));
        }
        if(StringUtils.isNotEmpty(beginTime) && StringUtils.isNotEmpty(endTime)){
            boolQueryBuilder.must(new RangeQueryBuilder("createTimeStr.keyword").gte(beginTime).lte(endTime).format("yyyy-MM-dd HH:mm:ss"));
        }
        Map<String, String> sortField = new HashMap<>();
        sortField.put("createTimeStr.keyword", "desc");
        RetrievalSearchResult list = dynamicSearchService.list(INDEX, boolQueryBuilder, null, null, sortField, null, pageNum, pageSize);
        List<Map<String, Object>> records = list.getRecords();


        // 指定 CSV 文件名
        String csvFileName = "data_"+ DateUtils.dateTimeNow() +".csv";
        response.setContentType("text/csv;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(csvFileName, Constants.UTF8));
        Set<String> fields = ((Map<String, Object>) records.get(0).get("params")).keySet();

        // 创建 FileWriter 对象
        try (PrintWriter writer = response.getWriter()) {
            // 写入标题行
            writer.write(String.join(",", fields));
            writer.write("\n");

            // 写入数据行
            for (Map<String, Object> data: records) {
                Map<String, Object> paramsMap = (Map<String, Object>) data.get("params");
                for(String field: fields){
                    writer.write(new String((paramsMap.get(field)+"").getBytes("UTF-8")));
                    writer.write(",");
                }
                writer.write("\n");
            }

            writer.flush();
            System.out.println("CSV file created successfully.");
        } catch (IOException e) {
            System.out.println("Failed to create CSV file: " + e.getMessage());
        }
    }



}
